package cn.com.yusys.yusp.admin.service;

import cn.com.yusys.yusp.admin.domain.AdminSmAuthReco;
import cn.com.yusys.yusp.admin.repository.mapper.AdminSmAuthRecoMapper;
import cn.com.yusys.yusp.commons.mapper.CommonMapper;
import cn.com.yusys.yusp.commons.service.CommonService;
import cn.com.yusys.yusp.commons.util.DateUtil;
import cn.com.yusys.yusp.commons.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @version 1.0.0
 * @项目名称: yusp-admin
 * @类名称: AdminSmAuthRecoService
 * @类描述: 资源对象关系配置
 * @功能描述:
 * @创建人: hujun3@yusys.com.cn
 * @创建时间: 2017-12-20 17:19
 * @修改备注:
 * @修改记录: 修改时间    修改人员    修改原因
 * modify by Cytus_ at 20180904 修改sonar扫描出现的bug， 将该类方法中finally中出现的return语句移至finally块外
 * -------------------------------------------------------------
 * @Copyright (c) 2018宇信科技-版权所有
 */
@Service
public class AdminSmAuthRecoService extends CommonService {
    private Logger logger = LoggerFactory.getLogger(AdminSmAuthRecoService.class);

    @Autowired
    private AdminSmAuthRecoMapper mapper;
    /*@Autowired
    private IClientService clientService;*/

    @Override
    protected CommonMapper<?> getMapper() {
        return mapper;
    }

    /**
     * @方法名称: getList
     * @方法描述: 查询对象资源关系数据
     * @参数与返回说明: 对象类型 objectType|资源类型 resType|对象记录编号 objectId
     * @算法描述:
     */
    @Transactional(readOnly = true)
    public List<Map<String, Object>> getList(String objectType, String resType, String objectId, String sysId) {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("objectType", objectType);
        paramMap.put("resType", resType.split(","));
        paramMap.put("objectId", objectId);
        paramMap.put("sysId", sysId);
        return mapper.getObjectResourcInfo(paramMap);
    }

    /**
     * @方法名称: getList
     * @方法描述: 查询对象资源关系数据
     * @参数与返回说明: 对象类型 objectType|资源类型 resType|对象记录编号 objectId
     * @算法描述:
     */
    @Transactional(readOnly = true)
    public List<Map<String, Object>> getExportData(String objectType, String resType, String objectId) {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("objectType", objectType);
        paramMap.put("resourceType", resType.split(","));
        paramMap.put("objectId", objectId);
        return mapper.authEcoExportExcel(paramMap);
    }

    /**
     * @方法名称:selectMenuInfo
     * @方法描述:菜单树初始化查询
     * @参数与返回说明:
     * @算法描述:
     */
    @Transactional(readOnly = true)
    public List<Map<String, Object>> selectMenuTree(String sysId,boolean lazy,String id) {
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        if(lazy) {
        	Map<String, Object> paramMap=new HashMap<String, Object>();
        	paramMap.put("sysId", sysId);
        	paramMap.put("id", id);
        	list= mapper.queryMenuTreeLazy( paramMap);
        }else {
        	list=mapper.queryMenuTree(sysId);
        }
        return list;
    }

    /**
     * @方法名称:selectMenuInfo
     * @方法描述:数据权限树初始化查询
     * @参数与返回说明:
     * @算法描述:
     */
    @Transactional(readOnly = true)
    public List<Map<String, Object>> selectDataPowerTree(String sysId) {
        List<Map<String, Object>> list = mapper.queryDataPowerTree(sysId);
        return list;
    }

    /**
     * @方法名称: deleteInfo
     * @方法描述: 删除关系数据
     * @参数与返回说明: 对象类型 objectType|资源类型 resType|对象记录编号 objectId
     * @算法描述:
     */
    @SuppressWarnings("rawtypes")
    public int deleteInfo(String objectType, List resType, String objectId, String sysId) {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("objectType", objectType);
        paramMap.put("resType", resType);
        paramMap.put("objectId", objectId);
        paramMap.put("sysId", sysId);
        return mapper.deleteRelInfo(paramMap);
    }

    /**
     * @方法名称: saveRelate
     * @方法描述: 保存对象资源关系数据
     * @参数与返回说明:
     * @算法描述:逻辑：先把以前的数据删除，然后在新建关系数据
     */
    @Transactional(readOnly = false, rollbackFor = {Exception.class, RuntimeException.class})
    public int saveRelate(List<AdminSmAuthReco> list) {
        int result = 0;
        if (list.size() > 0) {
            List<String> ids = new ArrayList<String>();
            int length = list.size();
            for (int s = 0; s < length; s++) {
                ids.add(list.get(s).getAuthresId());
            }
            List<Map<String, Object>> listRes = this.mapper.quryUpIdById(ids);
            int listResSize = listRes.size();
            //先删除关系数据
            AdminSmAuthReco pool = list.get(0);
            List<String> resType = new ArrayList<String>();
            resType.add("M");
            resType.add("C");
            this.deleteInfo(pool.getAuthobjType(), resType, pool.getAuthobjId(), pool.getSysId());//删除菜单和控制点
            logger.info("Delete the old object resource relationship data-- {}", DateUtil.formatDateByDef());
            List<AdminSmAuthReco> datas = new ArrayList<AdminSmAuthReco>();
            //新建关系数据
            for (int i = 0; i < listResSize; i++) {
                AdminSmAuthReco info = new AdminSmAuthReco();
                Map<String, Object> map = listRes.get(i);
                info.setLastChgDt(DateUtil.formatDateByDef());//最近跟新时间
                info.setSysId(pool.getSysId());
                info.setAuthobjId(pool.getAuthobjId());
                info.setAuthobjType(pool.getAuthobjType());
                info.setLastChgUsr(pool.getLastChgUsr());
                info.setAuthRecoId(StringUtil.getUUID());//获取逐渐ID（UUID）
                if (map.get("menuId") != null) {
                    info.setAuthresId(map.get("menuId").toString());
                }
                if (map.get("menuType") != null) {
                    info.setAuthresType(map.get("menuType").toString());
                }

                datas.add(info);
                result = result + this.insert(getMapper(), info);
            }
            result = mapper.insertBatchByOracle(datas);//批量新增
            logger.info("New object resource relationship data-- |{}|{}| ---{}", pool.getAuthobjType(), pool.getAuthobjId(), DateUtil.formatDateByDef());
            //clientService.clearAllContrUrl(HeaderUtil.getAccessToken());
        }
        return result;
    }

    /**
     * @方法名称: saveRelate
     * @方法描述: 保存对象资源关系数据
     * @参数与返回说明:
     * @算法描述:逻辑：先把以前的数据删除，然后在新建关系数据
     */
    @Transactional(readOnly = false, rollbackFor = {Exception.class, RuntimeException.class})
    public int insertBatch(List<Map<String, Object>> menus, List<Map<String, Object>> ctrs) {
        int result = 0;
        try {
            if (menus.size() > 0) {
                List<String> ids = new ArrayList<String>();
                int length = menus.size();
                int ctrLength = ctrs.size();
                for (int s = 0; s < length; s++) {
                    Map<String, Object> pol = menus.get(s);
                    ids.add(pol.get("authresId").toString());
                }
                List<Map<String, Object>> listRes = this.mapper.quryUpIdById(ids);
                int listResSize = listRes.size();
                //先删除关系数据
                Map<String, Object> pool = menus.get(0);
                List<String> resType = new ArrayList<String>();
                resType.add("M");
                resType.add("C");
                this.deleteInfo(pool.get("authobjType").toString(), resType, pool.get("authobjId").toString(), pool.get("sysId").toString());//删除菜单和控制点
                logger.info("Delete the old object resource relationship data-- {}", DateUtil.formatDateByDef());
                //新建关系数据
                for (int i = 0; i < listResSize; i++) {//新增菜单授权数据
                    AdminSmAuthReco info = new AdminSmAuthReco();
                    Map<String, Object> map = listRes.get(i);
                    info.setLastChgDt(DateUtil.formatDateByDef());//最近跟新时间
                    info.setSysId(pool.get("sysId").toString());
                    info.setAuthobjId(pool.get("authobjId").toString());
                    info.setAuthobjType(pool.get("authobjType").toString());
                    info.setLastChgUsr(pool.get("lastChgUsr").toString());
                    //info.setAuthRecoId(getUuid());//获取逐渐ID（UUID）
                    if (map.get("id") != null) {
                        info.setAuthresId(map.get("id").toString());
                    }
                    if (map.get("menuId") != null) {
                        info.setMenuId(map.get("menuId").toString());
                    }
                    if (map.get("menuType") != null) {
                        info.setAuthresType(map.get("menuType").toString());
                    }

                    result = result + mapper.insert(info);
                }
                for (int s = 0; s < ctrLength; s++) {
                    Map<String, Object> map = ctrs.get(s);
                    AdminSmAuthReco info = new AdminSmAuthReco();
                    info.setLastChgDt(DateUtil.formatDateByDef());//最近跟新时间
                    info.setSysId(map.get("sysId").toString());
                    info.setAuthobjId(map.get("authobjId").toString());
                    info.setAuthobjType(map.get("authobjType").toString());
                    info.setLastChgUsr(map.get("lastChgUsr").toString());
                    info.setAuthresId(map.get("authresId").toString());
                    info.setMenuId(map.get("menuId").toString());
                    info.setAuthresType(map.get("authresType").toString());
                    result = result + mapper.insert(info);
                }
                logger.info("New object resource relationship data-- |{}|{}| ---{}", pool.get("authobjType"), pool.get("authobjId"), DateUtil.formatDateByDef());
                //clientService.clearAllContrUrl(HeaderUtil.getAccessToken());
            }
        } catch (Exception e) {
            throw e;
        }
        return result;
    }

    /**
     * @方法名称: saveRelate
     * @方法描述: 保存角色数据权限数据
     * @参数与返回说明:
     * @算法描述:逻辑：先把以前的数据删除，然后在新建关系数据
     */
    @Transactional(readOnly = false, rollbackFor = {Exception.class, RuntimeException.class})
    public int saveRoleDataPower(List<AdminSmAuthReco> list) {
        int result = 0;
        try {
            if (list.size() > 0) {
                int length = list.size();
                //先删除关系数据
                AdminSmAuthReco pool = list.get(0);
                List<String> resType = new ArrayList<String>();
                resType.add("D");
                this.deleteInfo(pool.getAuthobjType(), resType, pool.getAuthobjId(), pool.getSysId());//删除数据权限
                logger.info("Delete the old object resource relationship data--{} ", DateUtil.formatDateByDef());
                //新建关系数据
                for (int i = 0; i < length; i++) {
                    AdminSmAuthReco info = list.get(i);
                    info.setLastChgDt(DateUtil.formatDateByDef());//最近跟新时间
                    result = result + mapper.insert(info);
                }
                logger.info("New role data authorization relationship data-- |{}|{}| ---{}" + pool.getAuthobjType(), pool.getAuthobjId(), DateUtil.formatDateByDef());
                //clientService.clearAllContrUrl(HeaderUtil.getAccessToken());
            }
        } catch (Exception e) {
            throw e;
        }
        return result;
    }

    /**
     * @方法名称: saveCopyRelate
     * @方法描述: 保存复制对象资源关系数据
     * @参数与返回说明:
     * @算法描述:逻辑：先把获取复制对象关系数据，然后在新建被复制对象关系数据
     */
    @Transactional(readOnly = false, rollbackFor = {Exception.class, RuntimeException.class})
    public int saveCopyRelate(Map<?, ?> list) {
        int result = 0;
        try {
            if (list.size() > 0) {
                //先获取复制对象关系数据
                String sourObjectType = list.get("sourObjectType").toString();
                String sourObjectId = list.get("sourObjectId").toString();
                String builObjectType = list.get("builObjectType").toString();
                String builObjectId = list.get("builObjectId").toString();
                String sysId = list.get("sysId").toString();
                String lastChgUsr = list.get("lastChgUsr").toString();
                Map<String, Object> paramMap = new HashMap<String, Object>();
                List<String> resType = new ArrayList<String>();
                resType.add("M");
                resType.add("C");
                paramMap.put("objectType", sourObjectType);
                paramMap.put("resType", resType);
                paramMap.put("objectId", sourObjectId);
                paramMap.put("sysId", sysId);
                List<Map<String, Object>> datList = mapper.getObjectResourcInfo(paramMap);
                logger.info("Get copied object resource relationship data-- {}", DateUtil.formatDateByDef());

                this.deleteInfo(builObjectType, resType, builObjectId, sysId);//删除菜单和控制点
                //新建关系数据
                for (int i = 0; i < datList.size(); i++) {
                    AdminSmAuthReco info = new AdminSmAuthReco();
                    info.setAuthobjId(builObjectId);
                    info.setAuthobjType(builObjectType);
                    info.setAuthresType(datList.get(i).get("authresType").toString());
                    info.setAuthresId(datList.get(i).get("authresId").toString());
                    info.setLastChgDt(DateUtil.formatDateByDef());//最近跟新时间
                    info.setLastChgUsr(lastChgUsr);
                    info.setSysId(sysId);
                    info.setMenuId(datList.get(i).get("menuId").toString());
                    result = result + mapper.insertSelective(info);
                }
                logger.info("Copy object resource relationship data: new object resource relationship data-- |{}|{}| ---{}", builObjectId, builObjectType, DateUtil.formatDateByDef());
                //clientService.clearAllContrUrl(HeaderUtil.getAccessToken());
            }
        } catch (Exception e) {
            throw e;
        }
        return result;
    }

    /**
     * @方法名称: saveCopyDataPower
     * @方法描述: 保存复制对角色数据授权关系数据
     * @参数与返回说明:
     * @算法描述:逻辑：先把获取复制对象关系数据，然后在新建被复制对象关系数据
     */
    @Transactional(readOnly = false, rollbackFor = {Exception.class, RuntimeException.class})
    public int saveCopyDataPower(Map<?, ?> list) {
        int result = 0;
        try {
            if (list.size() > 0) {
                //先获取复制对象关系数据
                String sourObjectType = list.get("sourObjectType").toString();
                String sourObjectId = list.get("sourObjectId").toString();
                String builObjectType = list.get("builObjectType").toString();
                String builObjectId = list.get("builObjectId").toString();
                String lastChgUsr = list.get("lastChgUsr").toString();
                String sysId = list.get("sysId").toString();
                Map<String, Object> paramMap = new HashMap<String, Object>();
                List<String> resType = new ArrayList<String>();
                resType.add("D");
                paramMap.put("objectType", sourObjectType);
                paramMap.put("resType", resType);
                paramMap.put("objectId", sourObjectId);
                paramMap.put("sysId", sysId);
                List<Map<String, Object>> datList = mapper.getObjectResourcInfo(paramMap);
                logger.info("Get copied object resource relationship data-- {}", DateUtil.formatDateByDef());

                this.deleteInfo(builObjectType, resType, builObjectId, sysId);//删除数据权限
                //新建关系数据
                for (int i = 0; i < datList.size(); i++) {
                    AdminSmAuthReco info = new AdminSmAuthReco();
                    info.setAuthobjId(builObjectId);
                    info.setAuthobjType(builObjectType);
                    info.setAuthresType("D");
                    info.setAuthresId(datList.get(i).get("authresId").toString());
                    info.setLastChgDt(DateUtil.formatDateByDef());//最近跟新时间
                    info.setLastChgUsr(lastChgUsr);
                    info.setSysId(sysId);

                    //update 添加菜单id
                    info.setMenuId(datList.get(i).get("menuId").toString());
                    result = result + mapper.insertSelective(info);
                }
                logger.info("Copy role data authorization: new object resource relationship data-- |{}|{}| ---{}", builObjectId, builObjectType, DateUtil.formatDateByDef());
                // clientService.clearAllContrUrl(HeaderUtil.getAccessToken());
            }
        } catch (Exception e) {
            throw e;
        }
        return result;
    }

    /**
     * @param map
     * @return 授权数据删除count
     */
    public int deleteDatainfo(Map<String, Object> map) {
        int n = 0;
        String sysId = String.valueOf(map.get("sysId"));
        String authobjId = String.valueOf(map.get("authobjId"));
        if (!"".equals(sysId) && !"".equals(authobjId) && map.get("authresType") != null && !((List) map.get("authresType")).isEmpty()) {
            List<String> list = (List) map.get("authresType");
            for (int i = 0; i < list.size(); i++) {
                AdminSmAuthReco adminSmAuthReco = new AdminSmAuthReco();
                adminSmAuthReco.setSysId(sysId);
                adminSmAuthReco.setAuthobjId(authobjId);
                adminSmAuthReco.setAuthresType(list.get(i));
                n = n + this.delete(adminSmAuthReco);
            }
        }
        return n;
    }
}
